/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.tbp.persitence.dao.impl;

import br.com.tbp.exception.PersistenciaException;
import br.com.tbp.model.domain.Consultor;
import br.com.tbp.model.domain.Visita;
import br.com.tbp.persitence.GerenciadorDeConexao;
import br.com.tbp.persitence.GerenciadorDeQuery;
import br.com.tbp.persitence.dao.FunilVendaDao;
import br.com.tbp.utils.DateUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @author Diego
 */
public class FunilVendaDaoImpl implements FunilVendaDao {

    private Connection conn = null;
    private PreparedStatement pr = null;
    private ResultSet rs = null;

    public void registrarVisita(Visita visita) throws PersistenciaException {
        if (visita == null) {
            throw new PersistenciaException("Não foi informado a visita a cadastrar.");
        }
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.insert"),
                    Statement.RETURN_GENERATED_KEYS);
            pr.setDate(1, DateUtils.dataObjetoParaDataBancoDeDados(visita.getData()));
            pr.setString(2, visita.getRazaoSocial());
            pr.setString(3, visita.getCnpj());
            pr.setString(4, visita.getResponsavel());
            pr.setString(5, visita.getContato());
            pr.setString(6, visita.getTermometro());
            pr.setString(7, visita.getQtdeLinhas());
            pr.setString(8, visita.getQtdeModens());
            pr.setString(9, visita.getMotivo());
            pr.setString(10, visita.getPortabilidade());
            pr.setString(11, visita.getPrincipalOfensor());
            pr.setString(12, visita.getObs());
            pr.setLong(13, visita.getConsultor().getId());
            pr.executeUpdate();

            rs = pr.getGeneratedKeys();
            rs.next();
            long id = rs.getLong(1);
            visita.setId(id);

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível cadastrar a visita.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
    }

    public void atualizarVisita(Visita visita) throws PersistenciaException {
        if (visita == null) {
            throw new PersistenciaException("Não foi informado a visita a atualizar.");
        }
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.update"));
            pr.setDate(1, DateUtils.dataObjetoParaDataBancoDeDados(visita.getData()));
            pr.setString(2, visita.getRazaoSocial());
            pr.setString(3, visita.getCnpj());
            pr.setString(4, visita.getResponsavel());
            pr.setString(5, visita.getContato());
            pr.setString(6, visita.getTermometro());
            pr.setString(7, visita.getQtdeLinhas());
            pr.setString(8, visita.getQtdeModens());
            pr.setString(9, visita.getMotivo());
            pr.setString(10, visita.getPortabilidade());
            pr.setString(11, visita.getPrincipalOfensor());
            pr.setString(12, visita.getObs());
            pr.setLong(13, visita.getId());
            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível atualizar a visita.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr);
        }
    }

    public List<Visita> findVisitas(Consultor consultor) throws PersistenciaException {
        List<Visita> lista = new ArrayList<Visita>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            if(consultor != null) {
                pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select.consultor"));
                pr.setLong(1, consultor.getId());
            } else {
                pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select"));
            }
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Visita c = this.criarVisita(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as visitas pelo consultor.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }

    public List<Visita> findAllVisitas(Consultor consultor) throws PersistenciaException {
        List<Visita> lista = new ArrayList<Visita>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select.all.consultor"));
            pr.setLong(1, consultor.getId());
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Visita c = this.criarVisita(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as visitas pelo consultor.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }

    public List<Visita> findVisitasByPeriod(Date date1, Date date2) throws PersistenciaException {
        List<Visita> lista = new ArrayList<Visita>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select.periodo"));
            pr.setDate(1, DateUtils.dataObjetoParaDataBancoDeDados(date1));
            pr.setDate(2, DateUtils.dataObjetoParaDataBancoDeDados(date2));
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Visita c = this.criarVisita(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as visitas pelo periodo.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }

    public List<Visita> findVisitasByPeriodAndConsultor(Date date1, Date date2, Consultor consultor) throws PersistenciaException {
        List<Visita> lista = new ArrayList<Visita>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select.periodo.consultor"));
            pr.setDate(1, DateUtils.dataObjetoParaDataBancoDeDados(date1));
            pr.setDate(2, DateUtils.dataObjetoParaDataBancoDeDados(date2));
            pr.setLong(3, consultor.getId());
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Visita c = this.criarVisita(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as visitas pelo periodo e consultor.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }

    private Visita criarVisita(ResultSet rs) throws PersistenciaException {
        Visita e = null;
        try {
            e = new Visita(rs.getLong("id"));
            e.setData(DateUtils.dataBancoDeDadosParaDataObjeto(
                    rs.getDate("data")));
            e.setRazaoSocial(rs.getString("razao_social"));
            e.setCnpj(rs.getString("cnpj"));
            e.setResponsavel(rs.getString("responsavel"));
            e.setContato(rs.getString("contato"));
            e.setTermometro(rs.getString("termometro"));
            e.setQtdeLinhas(rs.getString("linhas"));
            e.setQtdeModens(rs.getString("modens"));
            e.setMotivo(rs.getString("motivo"));
            e.setPortabilidade(rs.getString("portabilidade"));
            e.setPrincipalOfensor(rs.getString("principal_ofensor"));
            e.setObs(rs.getString("obs"));
            e.setConsultor(new Consultor(rs.getLong("id_consultor"), rs.getString("nome")));
        } catch (SQLException sqlex) {
            StringBuilder msg = new StringBuilder("Não foi possível obter os dados da visita.");
            msg.append("\nMotivo: ").append(sqlex.getMessage());
            throw new PersistenciaException(msg.toString());
        }
        return e;
    }

    public List<Visita> findVisitasByRazaoSocial(String razaoSocial, Consultor consultor) throws PersistenciaException {
        List<Visita> lista = new ArrayList<Visita>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            if (consultor != null) {
                pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select.razao.consultor"));
                pr.setLong(2, consultor.getId());
            } else {
                pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("visita.select.razao"));
            }
            pr.setString(1, "%" + razaoSocial + "%");
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Visita c = this.criarVisita(rs);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as visitas pela razão social.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }
}
